﻿using System;
using System.Globalization;
using OpenTap.Plugins.Interfaces.Common;
using OpenTap.Plugins.Interfaces.PulseGenerator;

namespace OpenTap.Plugins.PulseGenerator
{
    [Display("Keysight 81150A Driver", Group: "OpenTap.Plugins", Description: ("Keysight Pulse Function Arb Generator driver."))]
    public class Keysight81150A : ScpiInstrument, IPulseGen
    {
        public Keysight81150A()
        {
            Name = "PulsGen";
        }
        /// <summary>
        /// Open procedure for the instrument.
        /// </summary>
        public override void Open()
        {
            base.Open();
            Reset();
        }

        /// <summary>
        /// Close procedure for the instrument.
        /// </summary>
        public override void Close()
        {
            Log.Info("PulsGen : Close");
            SetOutputState(EState.Off);
            base.Close();
        }

        /// <inheritdoc />
        public void SetArmingSource(EPulsGenArmingSource armingSource)
        {
            ScpiCommand(":ARM:SOUR " + Scpi.Format("{0}", armingSource));
        }

        /// <inheritdoc />
        public void SetFuncOutput(EPulsGenFuncOutput outputType)
        {
            ScpiCommand(":FUNC " + Scpi.Format("{0}", outputType));
        }

        /// <inheritdoc />
        public void SetTriggerState(EPulsGenArmingSource armSource, EState triggeredMode, EState gateMode, EState continuosMode)
        {
            throw new NotImplementedException();
        }

        /// <inheritdoc />
        public void SetFrequency(double freqInHz)
        {
            if (freqInHz <= 0) throw new ArgumentOutOfRangeException(nameof(freqInHz));
            ScpiCommand(":FREQ " + freqInHz.ToString("#.000", CultureInfo.InvariantCulture) + "Hz");
        }

        /// <inheritdoc />
        public double GetFrequency()
        {
            return ScpiQuery<double>(":FREQ?");
        }

        /// <inheritdoc />
        public void SetDelay(double delInSec)
        {
            if (delInSec < 0) throw new ArgumentOutOfRangeException(nameof(delInSec));
            ScpiCommand("PULS:DEL " + delInSec.ToString("#.000", CultureInfo.InvariantCulture)  + "SEC");
        }

        /// <inheritdoc />
        public void SetAmplitude(double ampInVolts)
        {
            if (ampInVolts <= 0) throw new ArgumentOutOfRangeException(nameof(ampInVolts));
            ScpiCommand(":VOLT " + ampInVolts.ToString("#.000", CultureInfo.InvariantCulture) + "Vpp");
        }

        /// <inheritdoc />
        public double GetAmplitude()
        {
            return ScpiQuery<double>(":VOLT?");
        }

        /// <inheritdoc />
        public void SetDcOffset(double offVolt)
        {
            ScpiCommand("VOLT1:OFFS " + offVolt.ToString("#.000", CultureInfo.InvariantCulture) + "V");
        }

        /// <inheritdoc />
        public void SetLoadImpedance(double loadImp)
        {
            if (loadImp <= 0) throw new ArgumentOutOfRangeException(nameof(loadImp));
            ScpiCommand("OUTP:IMP:EXT " + loadImp.ToString("#.000", CultureInfo.InvariantCulture) + "Ohm");
        }

        /// <inheritdoc />
        public void SetOutputImpedance(double outputImp)
        {
            if (outputImp <= 0) throw new ArgumentOutOfRangeException(nameof(outputImp));
            ScpiCommand("OUTP:IMP " + outputImp.ToString("#.000", CultureInfo.InvariantCulture) + "Ohm");
        }

        /// <inheritdoc />
        public void SetDutyCycle(decimal percentage)
        {
            if (percentage <= 0) throw new ArgumentOutOfRangeException(nameof(percentage));
            ScpiCommand("FUNC1:SQU:DCYC " + percentage.ToString("#.000", CultureInfo.InvariantCulture) + "");
        }

        /// <inheritdoc />
        public void SetPolarity(EPulsGenPolarity polarity)
        {
            ScpiCommand("OUTP:POL " + Scpi.Format("{0}", polarity));
        }

        /// <inheritdoc />
        public void SetOutputState(EState outputState)
        {
            ScpiCommand("OUTP " + Scpi.Format("{0}", outputState));
        }

        /// <inheritdoc />
        public void SetComplement(EState compState)
        {
            ScpiCommand("OUTP:COMP " + Scpi.Format("{0}", compState));
        }

        #region Implementation of IScpi

        public void Clear()
        {
            ScpiCommand("*CLS");
        }

        #endregion
    }
}
